package l1j.opqlo.NewSystem.Extension;

import java.lang.reflect.Constructor;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.opqlo.Server.L1World.L1World;
import l1j.server.Thread.PcOtherThreadPool;
import l1j.server.server.GetNowTime;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.model.Getback;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_MapID;
import l1j.server.server.serverpackets.S_OtherCharPacks;
import l1j.server.server.serverpackets.S_OwnCharPack;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_Weather;
import l1j.server.server.templates.L1Npc;

public class CrackTime {

	public class GameStart extends TimerTask {

		private final int _Delaytime;
		private int time;

		public GameStart(final int time) {
			this._Delaytime = time;
			CrackTime.this.spawnCrack();
		}

		public void begin() {

			final Timer timer = new Timer();
			// timer.schedule(this, _Delaytime); // 延遲時間
			timer.scheduleAtFixedRate(this, this._Delaytime, this._Delaytime);
		}

		@Override
		public void run() {

			switch (GetNowTime.GetNowHour()) {
			case 1:
			case 4:
			case 7:
			case 10:
			case 13:
			case 16:
			case 19:
			case 22:
				L1World.getInstance().broadcastServerMessage(
						"\\fT時空裂痕即將於1分鐘後關閉...");
				this.time = 55;
				break;
			}
			while (this.time > 0) {
				this.time--;
				if (CrackTime.this._Start) {
					CrackTime.this._Start = false;
				}
				if (this.time <= 0) {
					_locationName = null;
					L1World.getInstance().broadcastServerMessage("\\fT時空裂痕關閉了...");
					CrackTime.this.clear();
					this.cancel();
					break;
				}
				try {
					Thread.sleep(1000);
				} catch (final InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	class Teleport implements Runnable {

		private int _to_x = 0;
		private int _to_y = 0;
		private short _to_mapId = 0;

		public Teleport(int to_x, int to_y, short to_mapId) {
			this._to_x = to_x;
			this._to_y = to_y;
			this._to_mapId = to_mapId;
		}

		@Override
		public void run() {
			try {
				Thread.sleep(600);
				for (;;) {
					if (CrackTime.this._npc._destroyed) {
						return;
					}

					for (final L1Object obj : L1World.getInstance().getVisiblePoint(CrackTime.this._npc.getLocation(),1)) {
						if (obj instanceof L1PcInstance) {
							final L1PcInstance target = (L1PcInstance) obj;
							final L1Location tmp_loc = new L1Location(
									this._to_x, this._to_y, this._to_mapId);
							final L1Location rnd_loc = tmp_loc.randomLocation(1, 5, false);
							L1Teleport.teleport(target, rnd_loc.getX(),	rnd_loc.getY(), (short) rnd_loc.getMapId(),target.getHeading(), true);
						}
					}
					Thread.sleep(1000);
				}
			} catch (final Exception e) {
				_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			}
		}
	}

	public class TimerS extends TimerTask {
		private final int _Delaytime;

		public TimerS(final int time) {
			this._Delaytime = time;
		}

		public void begin() {
			final Timer timer = new Timer();
			// timer.schedule(this, _Delaytime); // 延遲時間
			timer.scheduleAtFixedRate(this, this._Delaytime, this._Delaytime);
		}

		@Override
		public void run() {
			final int hour = GetNowTime.GetNowHour();
			switch (hour) {
			case 0:
			case 3:
			case 6:
			case 9:
			case 12:
			case 15:
			case 18:
			case 21:
				if (GetNowTime.GetNowMinute() < 55) {
					CrackTime.this._Start = true;
				}
				break;
			}

			if (CrackTime.this._Start) {
				
				switch(hour){
				case 0:
					_mapid = 1002;
					_x =32792;
					_y =32614;
					break;
				case 3:
					_mapid = 9912;
					_x =32856;
					_y =32681;
					break;
				case 6:
					_mapid = 1002;
					_x =32792;
					_y =32614;
					break;
				case 9:
					_mapid = 9912;
					_x =32856;
					_y =32681;
					break;
				case 12:
					_mapid = 1002;
					_x =32792;
					_y =32614;
					break;
				case 15:
					_mapid = 9912;
					_x =32856;
					_y =32681;
					break;
				case 18:
					_mapid = 1002;
					_x =32792;
					_y =32614;
					break;
				case 21:
					_mapid = 9912;
					_x =32856;
					_y =32681;
					break;
				}
				
				final GameStart Start = new GameStart(5000);
				Start.begin();
				this.cancel();
			} else {
				CrackTime.this.PcGohome();

			}
		}

	}

//	private final HashMap<Integer, int[]> _mapList = new HashMap<Integer, int[]>();

//	private final HashMap<Integer, String> _mapNameList = new HashMap<Integer, String>();

	private static CrackTime _instance;

	private L1NpcInstance _npc;

	private static final Logger _log = Logger.getLogger(CrackTime.class
			.getName());

	private static String _locationName;

	public static CrackTime get() {

		if (_instance == null) {
			_instance = new CrackTime();
		}
		return _instance;
	}

	private short _mapid = 1002;
	private int _x =0;
	private int _y =0;

	private boolean _Start = false;

	public CrackTime() {

//		this._mapList.put(new Integer(1), new int[] { 33002, 32732, 1011 });// 腰帶
//		this._mapList.put(new Integer(2), new int[] { 32937, 32803, 1005 });// 7階段武器
//		this._mapList.put(new Integer(3), new int[] { 32753, 33050, 1017 });// 7階段防具
//
//		this._mapNameList.put(new Integer(1), "高階皮帶區");
//		this._mapNameList.put(new Integer(2), "七階武器特區");
//		this._mapNameList.put(new Integer(3), "七階防具特區");

		final TimerS timer = new TimerS(30000);
		timer.begin();
	}

	private void clear() {

		this._npc.deleteMe();
		this.PcGohome();
		this.NpcDelete();

		final TimerS timer = new TimerS(60000);
		timer.begin();
	}

	private void createCrack(final int x, final int y, final short mapId,
			final int to_x, final int to_y, final short to_mapId) {
		try {
			final L1Npc l1npc = NpcTable.getInstance().getTemplate(71254);

			if (l1npc == null) {
				return;
			}

			final String s = l1npc.getImpl();
			final Constructor<?> constructor = Class.forName(
					"l1j.server.server.model.Instance." + s + "Instance")
					.getConstructors()[0];
			final Object aobj[] = { l1npc };
			final L1NpcInstance npc = (L1NpcInstance) constructor
					.newInstance(aobj);

			npc.setId(IdFactory.getInstance().nextId());
			npc.setX(x);
			npc.setY(y);
			npc.setMap(mapId);
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(0);

			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);

			final Teleport teleport = new Teleport(to_x, to_y, to_mapId);
			PcOtherThreadPool.get().execute(teleport);

			this._npc = npc;

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	public String getCrackLocName() {
		return _locationName;
	}

	private void NpcDelete() {
		for (final Object obj : L1World.getInstance().getVisibleObjects(this._mapid).values()) {
			if (obj instanceof L1NpcInstance) {
				final L1NpcInstance npc = (L1NpcInstance) obj;
				npc.deleteMe();
			}
		}
	}

	private void PcGohome() {
		for (final Object obj : L1World.getInstance()
				.getVisibleObjects(this._mapid).values()) {
			if (obj instanceof L1PcInstance) {
				final L1PcInstance pc = (L1PcInstance) obj;
				if (pc != null) {
					if (pc.isDead()) {
						this.reStartPlayer(pc);
					} else {
						// 傳送至威頓村
						L1Teleport.teleport(pc, 32795, 32863, (short) 1000,pc.getHeading(), true);
					}
				}
			}
		}
	}

	/** 副本內死亡的玩家重新開始 */
	private void reStartPlayer(final L1PcInstance pc) {
		// pc.stopPcDeleteTimer();
		pc.stopPcDeleteTimer();
		final int[] loc = Getback.GetBack_Location(pc, true);

		pc.removeAllKnownObjects();
		pc.broadcastPacketAll(new S_RemoveObject(pc));

		pc.setCurrentHp(pc.getLevel());
		pc.set_food(40);
		pc.setStatus(0);
		L1World.getInstance().moveVisibleObject(pc, loc[2]);
		pc.setX(loc[0]);
		pc.setY(loc[1]);
		pc.setMap((short) loc[2]);
		pc.sendPackets(new S_MapID(pc.getMapId(), pc.getMap().isUnderwater()));
		pc.broadcastPacketAll(new S_OtherCharPacks(pc));
		pc.sendPackets(new S_OwnCharPack(pc));
		pc.sendPackets(new S_CharVisualUpdate(pc));
		pc.startHpRegeneration();
		pc.startMpRegeneration();
		pc.sendPackets(new S_Weather(L1World.getInstance().getWeather()));
		if (pc.getHellTime() > 0) {
			pc.beginHell();
		}
	}

	private void spawnCrack() {

		L1Location crack = null;
		L1Location crack_loc = null;
//		final int rnd = Random.nextInt(_mapList.size()) + 1;
//		final int[] loc = this._mapList.get(rnd);
		final int[] loc = {32797 , 32777 , 1784};
		crack = new L1Location(loc[0], loc[1], loc[2]);
		crack_loc = new L1Location(this._x, this._y, this._mapid);
//		_locationName = "\\fT【" + this._mapNameList.get(rnd) + "】出現時空裂痕...";
		_locationName = "\\fT【神恩主城】出現時空裂痕...";
		L1World.getInstance().broadcastServerMessage(_locationName);
		this.createCrack(crack.getX(), crack.getY(), (short) crack.getMapId(),
				crack_loc.getX(), crack_loc.getY(),
				(short) crack_loc.getMapId());

		// createCrack(crack_loc.getX(), crack_loc.getY(), (short)
		// crack_loc.getMapId(), crack.getX(), crack.getY(), (short)
		// crack.getMapId());
	}
}
